package tests.pl.shenlon.poker.cards;

import java.util.ArrayList;
import java.util.List;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

import pl.shenlon.poker.cards.Card;
import pl.shenlon.poker.cards.CardRank;
import pl.shenlon.poker.cards.CardSuit;

public class CardTest {

	private Card[] cards;

	@Before
	public void setUp() {
		cards = new Card[] { new Card(CardSuit.CLUBS, CardRank.JACK),
				new Card(CardSuit.SPADES, CardRank.JACK),
				new Card(CardSuit.CLUBS, CardRank.JACK),
				new Card(CardSuit.CLUBS, CardRank.ACE),
				new Card(CardSuit.CLUBS, CardRank.NINE), };
	}
	@Test
	public void testCardCompareTo() {
		Assert.assertTrue(cards[0].compareTo(cards[1]) == 0);
		Assert.assertTrue(cards[0].compareTo(cards[2]) == 0);
		Assert.assertTrue(cards[0].compareTo(cards[3]) < 0);
		Assert.assertTrue(cards[0].compareTo(cards[4]) > 0);
	}

	@Test
	public void testCardEquality() {
		Assert.assertFalse(cards[0].equals(cards[1]));
		Assert.assertTrue(cards[0].equals(cards[2]));
		Assert.assertFalse(cards[0].equals(cards[3]));
		Assert.assertFalse(cards[0].equals(cards[4]));
		Assert.assertFalse(cards[0].equals(null));
	}

	@Test
	public void testConstructorFromString() {
		Card card = new Card("A♣");
		Assert.assertEquals("A♣", card.toString());
		card = new Card("10♣");
		Assert.assertEquals("10♣", card.toString());
	}

	@Test
	public void testEqualsSuitAndRank() {
		Assert.assertTrue(cards[0].equals(CardSuit.CLUBS, CardRank.JACK));
		Assert.assertFalse(cards[0].equals(CardSuit.CLUBS, CardRank.EIGHT));
		Assert.assertFalse(cards[0].equals(CardSuit.DIAMONDS, CardRank.JACK));
		Assert.assertFalse(cards[0].equals(CardSuit.SPADES, CardRank.NINE));
	}

	@Test
	public void testHashCode() {
		for (CardSuit suit : CardSuit.values()) {
			for (CardRank rank : CardRank.values()) {
				Card card = new Card(suit, rank);
				Assert.assertEquals(suit.ordinal() * 20 + rank.ordinal(),
						card.hashCode());
			}
		}
	}

	@Test
	public void testHashCodeUnique() {
		List<Integer> hashCodes = new ArrayList<Integer>();
		for (CardSuit suit : CardSuit.values()) {
			for (CardRank rank : CardRank.values()) {
				Card card = new Card(suit, rank);
				Assert.assertFalse(hashCodes.contains(card.hashCode()));
				hashCodes.add(card.hashCode());
			}
		}
	}
}